package com.zboot.zbootadmin.project.system.user.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.zboot.zbootadmin.common.security.LoginUser;
import com.zboot.zbootadmin.common.security.service.TokenService;
import com.zboot.zbootadmin.common.utils.ExcelUtils;
import com.zboot.zbootadmin.common.utils.SecurityUtils;
import com.zboot.zbootadmin.common.utils.ServletUtils;
import com.zboot.zbootadmin.common.utils.UploadUtils;
import com.zboot.zbootadmin.project.system.role.entity.SysRole;
import com.zboot.zbootadmin.project.system.role.entity.SysUserRole;
import com.zboot.zbootadmin.project.system.role.entity.vo.RoleVo;
import com.zboot.zbootadmin.project.system.role.service.SysRoleService;
import com.zboot.zbootadmin.project.system.role.service.SysUserRoleService;
import com.zboot.zbootadmin.project.system.user.domain.SysUser;
import com.zboot.zbootadmin.project.system.user.domain.dto.SearchDto;
import com.zboot.zbootadmin.project.system.user.mapper.SysUserMapper;
import com.zboot.zbootadmin.project.system.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Service
public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements UserService {

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    private SysRoleService sysRoleService;

    @Value("${file.profile}")
    private String savePath;

    @Override
    public SysUser selectUserByUserName(String userName) {
        return userMapper.selectUserByUserName(userName);
    }

    @Override
    public JSONObject getUserList(SearchDto searchDto) {
        QueryWrapper queryWrapper = new QueryWrapper();
        if (searchDto != null) {
            if (!"".equals(searchDto.getUserName()) && searchDto.getUserName() != null) {
                queryWrapper.like("user_name",searchDto.getUserName());
            }
            if (!"".equals(searchDto.getPhone()) && searchDto.getPhone() != null) {
                queryWrapper.like("phonenumber",searchDto.getPhone());
            }
            if (!"".equals(searchDto.getEmail()) && searchDto.getEmail() != null) {
                queryWrapper.like("email",searchDto.getEmail());
            }
            if (!"".equals(searchDto.getCreateTime()) && searchDto.getCreateTime() != null) {
                queryWrapper.like("create_time",searchDto.getCreateTime());
            }
        }
        if (searchDto.getPageNum()!=0&&searchDto.getPageSize()!=0) {
            PageHelper.startPage(searchDto.getPageNum(),searchDto.getPageSize());
        }
        if(tokenService.getLoginUser(ServletUtils.getRequest()).getUser().getIsAdmin()!=0) {
            queryWrapper.eq("create_by",tokenService.getLoginUser(ServletUtils.getRequest()).getUser().getUserName());
        }
        List<SysUser> result = this.list(queryWrapper);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("result",result);
        jsonObject.put("total",this.count(queryWrapper));
        return jsonObject;
    }

    @Override
    public List<SysUser> ExportUserList(MultipartFile uploadFile) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        // 用户信息
        SysUser user = loginUser.getUser();
        ExcelUtils<SysUser> excelUtils = new ExcelUtils<>();
        String [] properties = {"userName","nickName","email","phonenumber","sex","remark"};
        List<SysUser> userList = excelUtils.importUser(uploadFile,properties,SysUser.class);
        userList.stream().forEach(e->{
            if (e.getPassword()==null) {
                e.setPassword(new BCryptPasswordEncoder().encode(user.getUserName()));
            }

            if (e.getUserType()==null) {
                e.setUserType("00");
            }

            if (e.getStatus()==null) {
                e.setUserType("0");
            }

            if (e.getDelFlag()==null) {
                e.setDelFlag("0");
            }

            if (e.getCreateBy()==null) {
                e.setCreateBy(user.getUserName());
            }

            if (e.getIsAdmin()==null) {
                e.setIsAdmin(1);
            }

            if (e.getCreateTime()==null) {
                e.setCreateTime(new Date());
            }
            if (e.getUpdateTime()==null) {
                e.setUpdateTime(new Date());
            }
            if (e.getUserName().contains(".")) {
                int index = e.getUserName().indexOf(".");
                e.setUserName(e.getUserName().substring(0,index));
            }
            if (e.getSex().contains(".")) {
                int index = e.getSex().indexOf(".");
                e.setSex(e.getSex().substring(0,index));
            }
            if (e.getEmail().contains(".")) {
                int index = e.getEmail().indexOf(".");
                e.setEmail(e.getEmail().substring(0,index));
            }
            if (e.getPhonenumber().contains(".")) {
                int index = e.getPhonenumber().indexOf(".");
                e.setPhonenumber(e.getPhonenumber().substring(0,index));
            }
        });
        return userList;
    }

    @Override
    public void saveUser(SysUser sysUser) {
        sysUser.setCreateTime(new Date());
        sysUser.setUpdateTime(new Date());
        sysUser.setPassword(new BCryptPasswordEncoder().encode(sysUser.getPassword()));
        sysUser.setUserType("00");
        sysUser.setStatus("0");
        sysUser.setDelFlag("0");
        sysUser.setCreateBy(tokenService.getLoginUser(ServletUtils.getRequest()).getUsername());
        sysUser.setUpdateBy(tokenService.getLoginUser(ServletUtils.getRequest()).getUsername());
        sysUser.setIsAdmin(1);
        save(sysUser);
        Collection<SysUserRole> userRoles = new ArrayList<>();
        if (sysUser.getRoleIds()!=null && sysUser.getRoleIds().size()!=0) {
            sysUser.getRoleIds().stream().forEach(item->{
                SysUserRole sysUserRole = new SysUserRole();
                sysUserRole.setUserId(sysUser.getUserId());
                sysUserRole.setRoleId(Long.valueOf(item));
                userRoles.add(sysUserRole);
            });
        }
        sysUserRoleService.saveBatch(userRoles);
    }

    @Override
    public SysUser getEditUser(String userId) {
        SysUser sysUser = getById(userId);
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",sysUser.getUserId());
        List<SysUserRole> sysUserRoles = sysUserRoleService.list(queryWrapper);
        List<String> roleIds = new ArrayList<>();
        sysUserRoles.stream().forEach(sysUserRole -> {
            roleIds.add(sysUserRole.getRoleId().toString());
        });
        if (roleIds.size()!=0) {
            QueryWrapper wrapper = new QueryWrapper();
            wrapper.in("role_id",roleIds);
            List<SysRole> sysRoles = sysRoleService.list(wrapper);
            sysUser.setRoles(sysRoles);
            List<RoleVo> roleVos = new ArrayList<>();
            sysRoles.stream().forEach(item->{
                RoleVo roleVo = new RoleVo();
                roleVo.setLabel(item.getRoleName());
                roleVo.setValue(item.getRoleId().toString());
                roleVos.add(roleVo);
                sysUser.setRoleVosObj(roleVos);
            });
        }
        return sysUser;
    }

    @Override
    public void edit(SysUser sysUser) {
        updateById(sysUser);
        if (sysUser.getRoleIds()!=null) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("user_id",sysUser.getUserId());
            List<SysUserRole> sysUserRoles = new ArrayList<>();
            sysUserRoleService.remove(queryWrapper);
            sysUser.getRoleIds().stream().forEach(item->{
                SysUserRole sysUserRole = new SysUserRole();
                sysUserRole.setRoleId(Long.valueOf(item));
                sysUserRole.setUserId(sysUser.getUserId());
                sysUserRoles.add(sysUserRole);
            });
            sysUserRoleService.saveBatch(sysUserRoles);
        }
    }

    @Override
    public List<RoleVo> getAllRoles() {
        List<RoleVo> roleVoArrayList = new ArrayList<>();
        sysRoleService.list().stream().forEach(obj->{
            RoleVo roleVo = new RoleVo();
            roleVo.setValue(String.valueOf(obj.getRoleId()));
            roleVo.setLabel(obj.getRoleName());
            roleVoArrayList.add(roleVo);
        });
        return roleVoArrayList;
    }

    @Override
    @Transactional
    public void deleteUser(String[] ids) {
        removeByIds(Arrays.asList(ids));
        Arrays.asList(ids).stream().forEach(item->{
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("user_id",item);
            sysUserRoleService.remove(queryWrapper);
        });

    }

    @Override
    public void resetPwd(String newPassword) {
        userMapper.resetPwd(SecurityUtils.encryptPassword(newPassword),tokenService.getLoginUser(ServletUtils.getRequest()).getUser().getUserId().toString());
    }

    @Override
    public String uploadPicture(HttpServletRequest request, MultipartFile file) {
        SysUser sysUser = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        JSONObject jsonObject =  UploadUtils.upload(file,savePath);
        String pictureUrl = "http://"+request.getServerName()+":8080"+jsonObject.getString("dir").substring(jsonObject.getString("dir").lastIndexOf("/")).replace("\\","")+"/"+jsonObject.getString("fileName");
        userMapper.uploadPicture(sysUser.getUserId().toString(),pictureUrl);
        return pictureUrl;
    }
}
